package com.github.ghsea.sso.client.security.shiro;

import com.github.ghsea.sso.client.config.ShiroConfig;
import com.github.ghsea.sso.client.security.cas.WebUtil;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.apache.shiro.web.filter.authc.UserFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component(value = "defaultFilter")
public class DefaultFilter extends UserFilter {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private ShiroConfig shiroConfig;

    @Autowired
    private LogoutFilter logoutFilter;

    @PostConstruct
    private void init() {
        String loginUrl = shiroConfig.computeCasLoginUrl();
        super.setLoginUrl(loginUrl);

        String logoutUrl = logoutFilter.getRedirectUrl() + "?" + "service=" + loginUrl;
        logoutFilter.setRedirectUrl(logoutUrl);
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        if (WebUtil.isTokenSession(request)) {
            outputNoLoginMessage(request, response);
            return false;
        } else {
            return super.onAccessDenied(request, response);
        }
    }

    private void outputNoLoginMessage(final ServletRequest request, final ServletResponse response) {
        saveRequest(request);

        Map notLoginRet = new HashMap<>();
        notLoginRet.put("code", 403);
        notLoginRet.put("status", "fail");
        notLoginRet.put("message", "没有登录，请登录");
        notLoginRet.put("data", super.getLoginUrl());

        WebUtil.writeJson(notLoginRet, response);
    }

    public DefaultFilter setShiroConfig(ShiroConfig shiroConfig) {
        this.shiroConfig = shiroConfig;
        return this;
    }

    public DefaultFilter setLogoutFilter(LogoutFilter logoutFilter) {
        this.logoutFilter = logoutFilter;
        return this;
    }
}
